#
# fusion.mai.nava
#
# Copyright 2007 Helsinki Institute for Information Technology
# and the authors.
#
# Authors: Ken Rimey <rimey@hiit.fi>
#

# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

from urllib2 import urlopen
from xml.etree import ElementTree as ET
from simplejson import dumps

namespaces = {
    'oai': 'http://www.openarchives.org/OAI/2.0/',
    'oai_dc': 'http://www.openarchives.org/OAI/2.0/oai_dc/',
    'dc': 'http://purl.org/dc/elements/1.1/',
    'atom': 'http://www.w3.org/2005/Atom',
    }

URL = ('http://search.nava.hu/oai/oai-dp.php'
       '?verb=GetRecord'
       '&identifier=%s'
       '&metadataPrefix=oai_dc')

def fetch_oai_dc_record(oai_id):
    f = urlopen(URL % oai_id)
    try:
        return f.read()
    finally:
        f.close()

def oai_dc_to_json(xml):
    document = ET.fromstring(xml)
    record = document.find(nspath('oai:GetRecord/oai:record'))
    id = record.findtext(nspath('oai:header/oai:identifier'))
    dc = record.find(nspath('oai:metadata/oai_dc:dc'))

    json = {}
    #json['xmlns'] = namespaces['atom']
    json['xmlns$dc'] = namespaces['dc']
    json['id'] = id

    for child in dc:
        if child.tag.startswith('{' + namespaces['dc'] + '}'):
            key = 'dc$' + child.tag.split('}')[1]
            value = child.text

            if key not in json:
                json[key] = value
            elif not isinstance(json[key], list):
                json[key] = [json[key], value]
            else:
                json[key].append(value)

    return json

def atomize(json):
    json = dict(json)

    titles = get_list(json, 'dc$title')
    json['title'] = '\n'.join(titles)

    descriptions = get_list(json, 'dc$description')
    if descriptions:
        json['content'] = descriptions[0]

    dates = get_list(json, 'dc$date')
    if dates:
        for date in dates:
            if 'T' in date:
                json['published'] = date
                break
        else:
            json['published'] = dates[0]

    authors = get_list(json, 'dc$creator') + get_list(json, 'dc$publisher')
    authors = [{'name': name} for name in authors]
    if authors:
        if len(authors) > 1:
            json['author'] = authors
        else:
            json['author'] = authors[0]

    contributors = get_list(json, 'dc$contributor')
    contributors = [{'name': name} for name in contributors]
    if contributors:
        if len(contributors) > 1:
            json['contributor'] = contributors
        else:
            json['contributor'] = contributors[0]

    return json

def get_list(json, key):
    value = json.get(key, [])
    result = value if isinstance(value, list) else [value]
    return remove_duplicates(result)

def remove_duplicates(list):
    result = []
    for x in list:
        if x not in result:
            result.append(x)
    return result

def nspath(path):
    for prefix, uri in namespaces.iteritems():
        path = path.replace(prefix + ':', '{' + uri + '}')
    return path

if __name__ == '__main__':
    xml = fetch_oai_dc_record('oai:nava.hu:nava-335200')
    json = oai_dc_to_json(xml)
    json = atomize(json)
    print dumps(json, sort_keys=True, indent=2)
